package morenoapp.components.common;

import morenoapp.components.common.table.column.ColumnMeta;
import java.util.HashMap;
import java.util.Map;
import javax.swing.event.TableModelEvent;
import morenoapp.components.common.table.column.AbstractColumnMeta;
import morenoapp.model.listeners.MorenoModelAdapter;
import morenoapp.model.listeners.MorenoModelListener;
import morenoapp.model.data.MorenoAnswerFace;
import morenoapp.model.data.MorenoAnswerItemFace;
import morenoapp.model.data.MorenoQuestionFace;
import morenoapp.model.data.MorenoQuestionItemFace;
import morenoapp.model.data.MorenoRespondentFace;
import morenoapp.util.MorenoUtil;

/**
 *
 * @author dmitry.mamonov
 */
public abstract class AbstractMorenoRespondentsMatrixTableModel extends AbstractMatrixTableModel {

    private Map<Integer, ColumnMeta> matrixColumnsMeta = new HashMap<Integer, ColumnMeta>();

    public AbstractMorenoRespondentsMatrixTableModel() {
        MorenoModelListener modelListener = new MorenoModelAdapter() {

            @Override
            public void onRespondentsListChanged() {
                AbstractMorenoRespondentsMatrixTableModel.this.onRespondentsListChanged();
                fireTableChanged(new TableModelEvent(AbstractMorenoRespondentsMatrixTableModel.this, TableModelEvent.HEADER_ROW));
                fireTableChanged(new TableModelEvent(AbstractMorenoRespondentsMatrixTableModel.this));
            }

            @Override
            public void onRespondentChanged(MorenoRespondentFace changed) {
                System.out.println("Respondent changed: " + changed); //NOI18N
                int row = changed.getIndex();
                fireTableChanged(new TableModelEvent(AbstractMorenoRespondentsMatrixTableModel.this, row, row));
            }
        };
        getMorenoModel().addModelListener(modelListener);

    }

    @Override
    protected int getMiddleConlumnsCount() {
        return getMorenoModel().getRespondentsList().size();
    }

    @Override
    protected ColumnMeta getMiddleColumnMeta(final int index) {
        checkColumnRange(index);
        Integer key = Integer.valueOf(index);
        if (!matrixColumnsMeta.containsKey(key)) {
            matrixColumnsMeta.put(key, new AbstractColumnMeta("<html><p align=\"center\">" + (key + 1) + "</p>", String.class, 20) { //NOI18N

                public Object getRowValue(int row) {
                    return getMatrixValue(row, index);
                }
            });
        }
        return matrixColumnsMeta.get(key);
    }

    @Override
    protected int getMatrixSize() {
        return getMorenoModel().getRespondentsList().size();
    }

    /* implementation */
    /* Aux */
    public MorenoRespondentFace getRespondentByIndex(int row) {
        checkRowRange(row);
        return getMorenoModel().getRespondentsList().get(row);
    }

    public String getMatrixValue(int row, int col) {
        final String htmlPrefix = "<html>"; //NOI18N
        final int htmlPrefixLength = htmlPrefix.length();
        StringBuilder selection = new StringBuilder(htmlPrefix);
        MorenoRespondentFace respondent = getRespondentByIndex(row);
        MorenoRespondentFace target = getRespondentByIndex(col);
        for (MorenoQuestionFace question : getQuestionsFilter().getFilteredQuestionList()) {
            MorenoAnswerFace respondentAnswer = respondent.getAnswerByQuestion(question);
            MorenoAnswerItemFace answerItem = respondentAnswer.getAnswerItemByRespondent(target);
            if (answerItem != null) {
                MorenoQuestionItemFace questionItem = answerItem.getQuestionItem();
                if (questionItem != null) {
                    if (selection.length() > htmlPrefixLength) {
                        selection.append(", "); //NOI18N
                    }
                    selection.append("<b>" + MorenoUtil.wrapTextWithColor(question.getColor(), question.getMarkerForQuestionItem(questionItem)) + "</b>"); //NOI18N
                }
            }
        }
        return selection.toString();
    }

    protected void onRespondentsListChanged(){
        //pass
    }
}
